from PySide2.QtWidgets import QDialog
from PySide2.QtCore import QMetaMethod, QObject, Signal, Qt


class DlgModelParams(QDialog):
    _shown = False  # 类属性来跟踪对话框是否已显示
    _existDict = {}  # { identification1:_instance1, identification2:_instance2,... }

    def __init__(self, parent=None):
        super().__init__(parent)

    def _setIdentification(self, identification):
        self._identification = identification

    @classmethod
    def show(cls, parent=None, params={}, identification=""):
        identification = f"{cls.__name__}_{identification}"
        if cls._shown and identification in cls._existDict:
            instance = cls._existDict[identification]
            instance.activateWindow()
            instance.raise_()
            instance.disconnectCustomSignals()
            return instance
        else:
            instance = cls(parent, params)  # 创建新实例并传入parent
            instance.setParent(parent)  # 设置父窗口
            instance._setIdentification(identification)
            QDialog.show(instance)  # 直接调用QDialog的show方法
            cls._shown = True
            cls._existDict[identification] = instance
            return instance

    def keyPressEvent(self, event):
        """直接捕获 Esc 键并触发 close()"""
        if event.key() == Qt.Key_Escape:
            self.close()  # 触发 closeEvent
        else:
            super().keyPressEvent(event)

    # def closeEvent(self, event):
    #     del self.__class__._existDict[self._identification]
    #     self.__class__._shown = False  # 使用类名访问类属性
    #     # event.accept()
    #     # self.reject()
    #     # self.deleteLater()  # 安全销毁旧实例
    #     super().closeEvent(event)
    
    def closeEvent(self, event):
        # 先移除字典引用
        if self._identification in self.__class__._existDict:
            del self.__class__._existDict[self._identification]
        
        # 更精确的显示状态管理
        if not self.__class__._existDict:  # 当没有实例存在时才设为False
            self.__class__._shown = False
        
        # 显式接受关闭事件
        event.accept()
        
        # 安全清理
        # self.disconnectCustomSignals()  # 确保断开所有信号
        # self.deleteLater()
        
        super().closeEvent(event)

    def disconnectCustomSignals(self):
        meta_object = self.metaObject()
        for i in range(meta_object.methodCount()):
            meta_method = meta_object.method(i)
            if meta_method.methodType() == QMetaMethod.Signal:
                signal_name = (
                    meta_method.name().data().decode("utf-8")
                )  # 获取字符串类型的信号名
                is_connected = self.isSignalConnected(meta_method)
                if is_connected and signal_name.endswith("_signal"):
                    signal = getattr(self, signal_name)
                    signal.disconnect()


class DlgModelMutliParams(DlgModelParams):

    def __init__(self, parent=None):
        super().__init__(parent)

    @classmethod
    def show(cls, parent=None, params={}, identification=""):
        identification = f"{cls.__name__}_{identification}"
        if cls._shown and identification in cls._existDict:
            instance = cls._existDict[identification]
            instance.activateWindow()
            instance.raise_()
            # instance.initData(params)
            instance.disconnectCustomSignals()
            return instance
        else:
            instance = cls(parent, params)  # 创建新实例并传入parent
            instance.setParent(parent)  # 设置父窗口
            instance._setIdentification(identification)
            QDialog.show(instance)  # 直接调用QDialog的show方法
            cls._shown = True
            cls._existDict[identification] = instance
            return instance


class DlgModeResetCls(DlgModelParams):

    def __init__(self, parent=None):
        super().__init__(parent)

    @classmethod
    def show(cls, parent=None, params=None, identification=""):
        identification = f"{cls.__name__}_{identification}"
        if cls._shown and identification in cls._existDict:
            old_instance = cls._existDict[identification]
            old_instance.deleteLater()  # 安全销毁旧实例
            del cls._existDict[identification]
            cls._shown = False

            instance = cls(parent, params)  # 创建新实例并传入parent
            instance.setParent(parent)  # 设置父窗口
            instance._setIdentification(identification)
            QDialog.show(instance)  # 直接调用QDialog的show方法
            cls._shown = True
            cls._existDict[identification] = instance
            return instance
        else:
            instance = cls(parent, params)  # 创建新实例并传入parent
            instance.setParent(parent)  # 设置父窗口
            instance._setIdentification(identification)
            QDialog.show(instance)  # 直接调用QDialog的show方法
            cls._shown = True
            cls._existDict[identification] = instance
            return instance

    # def deleteLater(self):
    #     """重写销毁方法，清理资源"""
    #     super().deleteLater()
